using System;
using System.Collections;
using System.Collections.Generic;

namespace ICSharpCode.TextEditor.Document
{
	public sealed class SpanStack : ICloneable, IEnumerable<Span>, IEnumerable
	{
		internal sealed class StackNode
		{
			public readonly StackNode Previous;

			public readonly Span Data;

			public StackNode(StackNode previous, Span data)
			{
				this.Previous = previous;
				this.Data = data;
			}
		}

		public struct Enumerator : IEnumerator<Span>, IEnumerator, IDisposable
		{
			private StackNode c;

			public Span Current => this.c.Data;

			object IEnumerator.Current => this.c.Data;

			internal Enumerator(StackNode node)
			{
				this.c = node;
			}

			public void Dispose()
			{
				this.c = null;
			}

			public bool MoveNext()
			{
				this.c = this.c.Previous;
				return this.c != null;
			}

			public void Reset()
			{
				throw new NotSupportedException();
			}
		}

		private StackNode top = null;

		public bool IsEmpty => this.top == null;

		public Span Pop()
		{
			Span data = this.top.Data;
			this.top = this.top.Previous;
			return data;
		}

		public Span Peek()
		{
			return this.top.Data;
		}

		public void Push(Span s)
		{
			this.top = new StackNode(this.top, s);
		}

		public SpanStack Clone()
		{
			SpanStack spanStack = new SpanStack();
			spanStack.top = this.top;
			return spanStack;
		}

		object ICloneable.Clone()
		{
			return this.Clone();
		}

		public Enumerator GetEnumerator()
		{
			return new Enumerator(new StackNode(this.top, null));
		}

		IEnumerator<Span> IEnumerable<Span>.GetEnumerator()
		{
			return this.GetEnumerator();
		}

		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.GetEnumerator();
		}
	}
}
